package com.buyouchina.web.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import com.buyouchina.bean.area.Province;
import com.buyouchina.bean.product.Account;
import com.buyouchina.bean.product.Product;
import com.buyouchina.bean.product.Statistical;
import com.buyouchina.bean.product.Account.AccountAreaType;
import com.buyouchina.bean.product.Account.AccountType;
import com.buyouchina.bean.product.Account.DateType;
import com.buyouchina.bean.product.Statistical.StatisticalType;
import com.buyouchina.service.area.ProvinceService;
import com.buyouchina.service.product.AccountService;
import com.buyouchina.service.product.StatisticalService;
import com.buyouchina.utils.DateUtils;

public class AutoAccount extends BaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Logger log=Logger.getLogger(AutoAccount.class);
	
	
	@Resource(name = "accountServiceBean")
	private AccountService accountService;
	@Resource(name = "statisticalServiceBean")
	private StatisticalService tongjiService;
	@Resource(name = "provinceServiceBean")
	private ProvinceService provinceService;

	private Account account;
	@SuppressWarnings("unchecked")
	private List accounts = new ArrayList();

	String hql;
	Object[] obs;
	Date[] dateTime;
	String cityid;
	String provinceid;

	enum SqlType {
		CITYANDCOUNTRY {
			public String getSql() {
				return "select a.areaType,a.product,sum(a.quantity),a.province from Account a "
						+ "where a.dateType=?1 and a.date between ?2 and ?3 "
						+ "group by a.product,a.province";
			}
		},
		STATE {
			public String getSql() {
				return "select a.areaType,a.product,sum(a.quantity) from Account a "
						+ "where a.dateType=?1 and a.date between ?2 and ?3 and a.province is null "
						+ "group by a.product";
			}
		};
		public abstract String getSql();
	}

	// 日统计
	public void dayAccount() {
		log.setLevel(Level.INFO);
		log.info("Quartz for yesterday of account ---start---");
		try {
			this.accountCityLevel();
			this.accountCountyLevel();
			this.accountStateLevel();
		} catch (Exception e) {
			e.printStackTrace();
			log.info("Quartz for yesterday of account ---failed---");
		}
		log.info("Quartz for yesterday of account ---end---");
	}

	// 今日统计
	public void todayAccount() {
		log.setLevel(Level.INFO);
		log.info("Quartz for today of account ---start---");

		try {
			dateTime = DateUtils.getTodayInterval();
			accounts = tongjiService.list(dateTime[0], dateTime[1],
					StatisticalType.PURCHASE);
			for (int i = 0; i < accounts.size(); i++) {
				obs = (Object[]) accounts.get(i);
				cityid = ((Province) obs[2]).getCityid();
				Province province = provinceService.find(Integer
						.parseInt(cityid));
				account = accountService.checkRecord(
						((Product) obs[1]).getId(), cityid, new Date());
				if (account != null) {
					account.setQuantity(account.getQuantity()
							+ ((Double) obs[0]));
					accountService.update(account);
				} else {
					account = new Account();
					account.setAreaType(AccountAreaType.CITYLEVEL);
					account.setProvince(province);// has bug 店铺必须具体到区
					account.setType(AccountType.PURCHASE);
					account.setProduct(((Product) obs[1]));
					account.setDate(new Date());
					account.setQuantity(((Double) obs[0]));
					account.setDateType(DateType.DAY);
					accountService.save(account);
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			log.info("Quartz for today of account ---failed---");
		}
		log.info("Quartz for today of account ---end---");
	}
	
	// 今日统计
	public void todayAccountCountry(){
		
	}

	// 周统计
	public void weekAccount() {
		log.setLevel(Level.INFO);
		log.info("Quartz for week of account ---start---");
		try {
			dateTime = DateUtils.getPreviousWeekInterval();
			xx(SqlType.CITYANDCOUNTRY.getSql(), DateType.DAY, dateTime[0],
					dateTime[1]);
			xx(SqlType.STATE.getSql(), DateType.DAY, dateTime[0], dateTime[1]);
		} catch (Exception e) {
			e.printStackTrace();
			log.info("Quartz for week of account ---failed---");
		}
		log.info("Quartz for week of account ---end---");
	}

	// 月统计
	public void monthAccount() {
		log.setLevel(Level.INFO);
		log.info("Quartz for month of account ---start---");
		try {
			dateTime = DateUtils.getPreviousMonthInterval();
			xx(SqlType.CITYANDCOUNTRY.getSql(), DateType.WEEK, dateTime[0],
					dateTime[1]);
			xx(SqlType.STATE.getSql(), DateType.WEEK, dateTime[0], dateTime[1]);
		} catch (Exception e) {
			e.printStackTrace();
			log.info("Quartz for month of account ---failed---");
		}
		log.info("Quartz for month of account ---end---");
	}

	// 年统计
	public void yearAccount() {
		log.setLevel(Level.INFO);
		log.info("Quartz for year of account ---start---");
		try {
			dateTime = DateUtils.getPreviousYearInterval();
			xx(SqlType.CITYANDCOUNTRY.getSql(), DateType.MONTH, dateTime[0],
					dateTime[1]);
			xx(SqlType.STATE.getSql(), DateType.MONTH, dateTime[0], dateTime[1]);
		} catch (Exception e) {
			e.printStackTrace();
			log.info("Quartz for year of account ---failed---");
		}

		log.info("Quartz for year of account ---end---");
	}

	private void xx(String hql, DateType type, Date startTime, Date endTime) {
		accounts = accountService.list(hql, type, startTime, endTime);
		for (int i = 0; i < accounts.size(); i++) {
			obs = (Object[]) accounts.get(i);
			account = new Account();
			account.setAreaType(((AccountAreaType) obs[0]));
			account.setType(AccountType.PURCHASE);
			account.setProduct(((Product) obs[1]));
			account.setQuantity(((Double) obs[2]));
			account.setDate(new Date());
			if (obs.length > 3) {
				account.setProvince(((Province) obs[3]));
			}
			if (type.equals(DateType.DAY)) {
				account.setDateType(DateType.WEEK);
			} else if (type.equals(DateType.WEEK)) {
				account.setDateType(DateType.MONTH);
			} else if (type.equals(DateType.MONTH)) {
				account.setDateType(DateType.YEAR);
			} else {
				System.out.print("error");
			}
			accountService.save(account);
		}
	}

	public void accountCityLevel() {
		Date[] dateTime = DateUtils.getPreviousDayInterval();

		List<Statistical> tongjiList = tongjiService.listByDate(dateTime[0],
				dateTime[1]);
		for (Statistical tongji : tongjiList) {
			cityid = provinceService.getCityId(tongji.getTo().getProvince()
					.getId());
			account = accountService.checkRecord(tongji.getProduct().getId(),
					cityid, new Date());
			if (account != null) {
				account.setQuantity(account.getQuantity()
						+ tongji.getQuantity());
				account.getTongjis().add(tongji);
				accountService.update(account);
			} else {
				account = new Account();
				account.setDateType(DateType.DAY);
				account.setAreaType(AccountAreaType.CITYLEVEL);
				account.setType(AccountType.PURCHASE);
				account.setDate(tongji.getDate());
				account.setProduct(tongji.getProduct());
				account.setQuantity(tongji.getQuantity());
				account.getTongjis().add(tongji);
				account.setProvince(provinceService.find(Integer
						.parseInt(cityid)));
				accountService.save(account);
			}
		}
	}

	public void accountCountyLevel() {
		List<Account> accounts = new ArrayList<Account>();
		accounts = accountService.list(DateUtils.getPreviousDay(), AccountAreaType.CITYLEVEL,
				null);
		for (Account ac : accounts) {
			provinceid = provinceService
					.getProvinceId(ac.getProvince().getId());

			account = accountService.checkRecord(ac.getProduct().getId(),
					provinceid, new Date());
			if (account != null) {
				account.setQuantity(account.getQuantity() + ac.getQuantity());
				accountService.update(account);
			} else {
				account = new Account();
				account.setDateType(DateType.DAY);
				account.setAreaType(AccountAreaType.COUNTYLEVEL);
				account.setType(AccountType.PURCHASE);
				account.setDate(ac.getDate());
				account.setProduct(ac.getProduct());
				account.setQuantity(ac.getQuantity());
				account.setProvince(provinceService.find(Integer
						.parseInt(provinceid)));
				accountService.save(account);
			}
		}
	}

	public void accountStateLevel() {

		List<Account> accounts = new ArrayList<Account>();
		accounts = accountService.list(DateUtils.getPreviousDay(), AccountAreaType.COUNTYLEVEL,
				null);
		for (Account ac : accounts) {

			account = accountService.checkRecord(ac.getProduct().getId(), null,
					new Date());
			if (account != null) {
				account.setQuantity(account.getQuantity() + ac.getQuantity());
				accountService.update(account);
			} else {
				account = new Account();
				account.setDateType(DateType.DAY);
				account.setAreaType(AccountAreaType.STATELEVEL);
				account.setType(AccountType.PURCHASE);
				account.setDate(ac.getDate());
				account.setProduct(ac.getProduct());
				account.setQuantity(ac.getQuantity());
				accountService.save(account);
			}
		}
	}

	public Account getAccount() {
		return account;
	}

	public void setAccount(Account account) {
		this.account = account;
	}

	@SuppressWarnings("unchecked")
	public List getAccounts() {
		return accounts;
	}

	@SuppressWarnings("unchecked")
	public void setAccounts(List accounts) {
		this.accounts = accounts;
	}
}
